/*
 * @Description: 创建集合类
 * @Autor: wangxin
 * @Date: 2020-06-12 14:34:38
 * @LastEditTime: 2020-06-12 20:10:44
 */
class Set {
  constructor() {
    this.items = {}
  }

  /**
   * 检验某个元素是否存在于集合中
   */
  has(element) {
    return element in this.items
    // return Object.hasOwnProperty.call(this.items, element)
  }

  /**
   * 添加元素
   */
  add(element) {
    if (this.has(element)) {
      return false
    }
    this.items[element] = element
    return true
  }

  /**
   * 删除元素
   */
  delete(element) {
    if (!this.has(element)) {
      return false
    }
    delete this.items[element]
    return true
  }

  /**
   * 清空集合
   */
  clear() {
    this.items = {}
  }

  /**
   * 返回集合中有多少元素
   */
  size() {
    // return Object.keys(this.items).length
    let count = 0
    for (let key in this.items) {
      if (this.items.hasOwnProperty(key)) {
        count++
      }
    }
    return count
  }

  /**
   * 返回集合中的所有元素
   */
  values() {
    let values = []
    for (let key in this.items) {
      if (this.items.hasOwnProperty(key)) {
        values.push(key)
      }
    }
    return values
  }

  /**
   * 并集
   */
  union(otherSet) {
    let unionSet = new Set()
    this.values().forEach((value) => unionSet.add(value))
    otherSet.values().forEach((value) => unionSet.add(value))
    return unionSet
  }

  /**
   * 交集
   */
  intersection(otherSet) {
    const intersectionSet = new Set()
    const values = this.values()
    const otherValues = otherSet.values()
    // 假设(优化交接迭代次数)
    let biggerSet = values
    let smallerSet = otherValues
    if (otherValues.length > values.length) {
      biggerSet = otherValues
      smallerSet = values
    }
    smallerSet.forEach((value) => {
      if (biggerSet.includes(value)) {
        intersectionSet.add(value)
      }
    })

    return intersectionSet
  }

  /**
   * 差集
   */
  difference(otherSet) {
    const differenceSet = new Set()
    this.values().forEach((value) => {
      if (!otherSet.has(value)) {
        differenceSet.add(value)
      }
    })
    return differenceSet
  }

  /**
   * 子集
   */
  isSubsetOf(otherSet) {
    if (this.size() > otherSet.size()) {
      return false
    }
    let isSubset = true
    this.values().every((value) => {
      if (!otherSet.has(value)) {
        isSubset = false
        return false
      }
      return true
    })
    return isSubset
  }
}

// 代码测试
// var setA = new Set()
// setA.add(1)
// setA.add(2)
// setA.add(3)
// setA.add(4)
// var setB = new Set()
// setB.add(3)
// setB.add(4)
// setB.add(5)
// console.log(setA.isSubsetOf(setB))
